﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using System.Text;
using System.Linq;

/// <summary>
/// 物品拾取管理器 - 处理物品生成、拾取和同步
/// </summary>
public class ItemPickupHelper : MonoBehaviour
{
    [Header("网络设置")]
    [SerializeField] private string serverUrl = "http://192.168.101.111:5000";
    
    [Header("预制体设置")]
    [SerializeField] private GameObject pickupItemPrefab;
    [SerializeField] private string defaultPrefabName = "PickupItem";
    
    [Header("拾取设置")]
    [SerializeField] private float pickupRange = 2.0f;
    [SerializeField] private KeyCode pickupKey = KeyCode.E;
    [SerializeField] private float syncInterval = 0.5f;
    
    [Header("多人竞争测试")]
    [SerializeField] private int concurrentPlayersCount = 5;
    [SerializeField] private float requestDelay = 0.01f; // 每个请求之间的微小延迟
    
    [Header("调试")]
    [SerializeField] private bool showDebugInfo = true;
    [SerializeField] private bool showGUI = true;
    
    // 网络引用
    private NetworkManager networkManager;
    
    // 物品管理
    private Dictionary<string, GameObject> spawnedItems = new Dictionary<string, GameObject>();
    private List<PickupItem> serverItems = new List<PickupItem>();
    
    // 玩家引用
    private Transform playerTransform;
    private string localPlayerId;
    
    // 状态
    private bool isInitialized = false;
    private float lastSyncTime = 0f;

    
    void Start()
    {
        // 获取NetworkManager引用
        networkManager = NetworkManager.Instance;
        if (networkManager == null)
        {
            Debug.LogError("未找到NetworkManager！");
            return;
        }
        
        // 等待网络连接后初始化
        StartCoroutine(WaitForNetworkConnection());
    }
    
    IEnumerator WaitForNetworkConnection()
    {
        Debug.Log("等待网络连接...");
        
        // 等待网络连接
        while (!networkManager.isConnected)
        {
            yield return new WaitForSeconds(0.1f);
        }
        
        // 获取本地玩家信息
        localPlayerId = GetLocalPlayerId();
        if (string.IsNullOrEmpty(localPlayerId))
        {
            Debug.LogError("无法获取本地玩家ID！");
            yield break;
        }
        
        // 查找玩家Transform
        FindPlayerTransform();
        
        // 初始化拾取系统
        isInitialized = true;
        Debug.Log("物品拾取系统已初始化");
        
        // 开始同步循环
        StartCoroutine(SyncItemsWithServer());
    }
    
    void Update()
    {
        if (!isInitialized || !networkManager.isConnected) return;
        
        // 拾取按键检测
        if (Input.GetKeyDown(pickupKey))
        {
            TryPickupNearestItem();
        }
    }
    
    void OnGUI()
    {
        if (!showGUI) return;
        
        GUILayout.BeginArea(new Rect(10, 100, 300, 400));
        GUILayout.BeginVertical("box");
        
        GUILayout.Label("物品拾取系统", new GUIStyle(GUI.skin.label) { fontSize = 16, fontStyle = FontStyle.Bold });
        
        GUILayout.Space(10);
        
        // 系统状态
        GUILayout.Label($"状态: {(isInitialized ? "已初始化" : "未初始化")}");
        GUILayout.Label($"网络: {(networkManager?.isConnected == true ? "已连接" : "未连接")}");
        GUILayout.Label($"玩家ID: {localPlayerId ?? "无"}");
        GUILayout.Label($"服务器物品数: {serverItems.Count}");
        GUILayout.Label($"本地物品数: {spawnedItems.Count}");
        
        GUILayout.Space(10);
        
        // 测试按钮
        GUI.enabled = isInitialized && networkManager?.isConnected == true;
        
        if (GUILayout.Button("在原点生成物品"))
        {
            StartCoroutine(SpawnItemAtOrigin());
        }
        
        if (GUILayout.Button("手动同步物品"))
        {
            StartCoroutine(SyncItemsFromServer());
        }
        
        if (GUILayout.Button("清理已拾取物品"))
        {
            StartCoroutine(CleanupPickedItems());
        }
        
        GUILayout.Space(5);
        
        // 多人竞争测试按钮
        if (GUILayout.Button("模拟多人同时拾取测试"))
        {
            StartCoroutine(SimulateConcurrentPickupTest());
        }
        GUI.backgroundColor = Color.white;
        
        // 测试参数显示
        GUILayout.Label($"测试参数: {concurrentPlayersCount}个虚拟玩家");
        GUILayout.Label($"请求间隔: {requestDelay * 1000:F0}ms");
        
        GUI.enabled = true;
        
        GUILayout.Space(10);
        
        // 操作提示
        GUILayout.Label($"按 {pickupKey} 键拾取附近物品");
        GUILayout.Label($"拾取范围: {pickupRange:F1} 米");
        
        GUILayout.EndVertical();
        GUILayout.EndArea();
    }
    
    /// <summary>
    /// 在原点生成物品
    /// </summary>
    public IEnumerator SpawnItemAtOrigin()
    {
        Debug.Log("请求在原点生成物品...");
        
        string url = $"{serverUrl}/api/Pickup/spawn-at-origin?prefabName={defaultPrefabName}";
        
        using (UnityWebRequest request = new UnityWebRequest(url, "POST"))
        {
            request.downloadHandler = new DownloadHandlerBuffer();
            request.SetRequestHeader("Content-Type", "application/json");
            
            yield return request.SendWebRequest();
            
            if (request.result == UnityWebRequest.Result.Success)
            {
                Debug.Log("物品生成成功");
                Debug.Log($"服务器响应: {request.downloadHandler.text}");
                
                // 立即同步物品列表
                yield return SyncItemsFromServer();
            }
            else
            {
                Debug.LogError($"生成物品失败: {request.error}");
                Debug.LogError($"响应内容: {request.downloadHandler.text}");
            }
        }
    }
    
    /// <summary>
    /// 尝试拾取最近的物品
    /// </summary>
    void TryPickupNearestItem()
    {
        if (playerTransform == null)
        {
            FindPlayerTransform();
            if (playerTransform == null) return;
        }
        
        // 查找范围内的物品
        var nearbyItems = FindNearbyItems();
        if (nearbyItems.Count == 0)
        {
            if (showDebugInfo)
                Debug.Log("附近没有可拾取的物品");
            return;
        }
        
        // 选择最近的物品
        var nearestItem = nearbyItems.OrderBy(item => 
            Vector3.Distance(playerTransform.position, spawnedItems[item.ItemId].transform.position)
        ).First();
        
        Debug.Log($"尝试拾取物品: {nearestItem.ItemId}");
        StartCoroutine(SendPickupRequest(nearestItem.ItemId));
    }
    
    /// <summary>
    /// 查找附近的物品
    /// </summary>
    List<PickupItem> FindNearbyItems()
    {
        if (playerTransform == null) return new List<PickupItem>();
        
        var nearbyItems = new List<PickupItem>();
        Vector3 playerPos = playerTransform.position;
        
        foreach (var item in serverItems)
        {
            if (item.IsPickedUp) continue;
            if (!spawnedItems.ContainsKey(item.ItemId)) continue;
            
            GameObject itemObj = spawnedItems[item.ItemId];
            float distance = Vector3.Distance(playerPos, itemObj.transform.position);
            
            if (distance <= pickupRange)
            {
                nearbyItems.Add(item);
            }
        }
        
        return nearbyItems;
    }
    
    /// <summary>
    /// 发送拾取请求到服务器
    /// </summary>
    IEnumerator SendPickupRequest(string itemId)
    {
        if (playerTransform == null) yield break;
        
        var pickupRequest = new PickupRequest(
            localPlayerId, 
            itemId, 
            playerTransform.position
        );
        
        string jsonData = JsonUtility.ToJson(pickupRequest);
        
        using (UnityWebRequest request = new UnityWebRequest($"{serverUrl}/api/Pickup/pickup", "POST"))
        {
            byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonData);
            request.uploadHandler = new UploadHandlerRaw(bodyRaw);
            request.downloadHandler = new DownloadHandlerBuffer();
            request.SetRequestHeader("Content-Type", "application/json");
            
            yield return request.SendWebRequest();
            
            if (request.result == UnityWebRequest.Result.Success)
            {
                try
                {
                    var response = JsonUtility.FromJson<PickupResponse>(request.downloadHandler.text);
                    
                    if (response.Success)
                    {
                        Debug.Log($"拾取成功: {response.Message}");
                        
                        // 立即移除本地物品对象
                        if (spawnedItems.TryGetValue(itemId, out GameObject itemObj))
                        {
                            spawnedItems.Remove(itemId);
                            Destroy(itemObj);
                        }
                        
                        // 更新服务器物品列表
                        serverItems = response.RemainingItems.ToList();
                    }
                    else
                    {
                        Debug.LogWarning($"拾取失败: {response.Message}");
                    }
                }
                catch (Exception ex)
                {
                    Debug.LogError($"解析拾取响应失败: {ex.Message}");
                }
            }
            else
            {
                Debug.LogError($"拾取请求失败: {request.error}");
            }
        }
    }
    
    /// <summary>
    /// 与服务器同步物品列表
    /// </summary>
    IEnumerator SyncItemsWithServer()
    {
        while (isInitialized && networkManager?.isConnected == true)
        {
            yield return new WaitForSeconds(syncInterval);
            yield return SyncItemsFromServer();
        }
    }
    
    /// <summary>
    /// 从服务器获取物品列表
    /// </summary>
    IEnumerator SyncItemsFromServer()
    {
        using (UnityWebRequest request = UnityWebRequest.Get($"{serverUrl}/api/Pickup/items"))
        {
            yield return request.SendWebRequest();
            
            if (request.result == UnityWebRequest.Result.Success)
            {
                try
                {
                    var response = JsonUtility.FromJson<ItemListResponse>(request.downloadHandler.text);
                    
                    if (response != null && response.Items != null)
                    {
                        // 更新服务器物品列表
                        var newServerItems = response.Items.Where(item => !item.IsPickedUp).ToList();
                        
                        // 检查是否有变化
                        if (!AreItemListsEqual(serverItems, newServerItems))
                        {
                            Debug.Log($"物品列表更新: {newServerItems.Count} 个可用物品");
                            serverItems = newServerItems;
                            UpdateLocalItems();
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug.LogError($"解析物品列表失败: {ex.Message}");
                }
            }
            else
            {
                Debug.LogError($"获取物品列表失败: {request.error}");
            }
        }
    }
    
    /// <summary>
    /// 更新本地物品对象
    /// </summary>
    void UpdateLocalItems()
    {
        // 移除不再存在的物品
        var itemsToRemove = spawnedItems.Keys.Where(id => 
            !serverItems.Any(item => item.ItemId == id)
        ).ToList();
        
        foreach (string itemId in itemsToRemove)
        {
            if (spawnedItems.TryGetValue(itemId, out GameObject itemObj))
            {
                Debug.Log($"移除物品: {itemId}");
                spawnedItems.Remove(itemId);
                Destroy(itemObj);
            }
        }
        
        // 添加新物品
        foreach (var item in serverItems)
        {
            if (!spawnedItems.ContainsKey(item.ItemId))
            {
                SpawnLocalItem(item);
            }
        }
    }
    
    /// <summary>
    /// 在本地生成物品对象
    /// </summary>
    void SpawnLocalItem(PickupItem item)
    {
        if (pickupItemPrefab == null)
        {
            Debug.LogError("拾取物品预制体未设置！");
            return;
        }
        
        Vector3 position = item.Position.ToVector3();
        Vector3 rotation = item.Rotation.ToVector3();
        
        GameObject itemObj = Instantiate(pickupItemPrefab, position, Quaternion.Euler(rotation));
        itemObj.name = $"PickupItem_{item.ItemId[..8]}";
        
        // 添加拾取物品组件
        var pickupComponent = itemObj.GetComponent<PickupItemBehaviour>();
        if (pickupComponent == null)
        {
            pickupComponent = itemObj.AddComponent<PickupItemBehaviour>();
        }
        
        pickupComponent.Initialize(item);
        
        spawnedItems[item.ItemId] = itemObj;
        
        if (showDebugInfo)
            Debug.Log($"生成本地物品: {item.ItemId[..8]} 在 {position}");
    }
    
    /// <summary>
    /// 清理已拾取的物品
    /// </summary>
    IEnumerator CleanupPickedItems()
    {
        using (UnityWebRequest request = new UnityWebRequest($"{serverUrl}/api/Pickup/cleanup", "POST"))
        {
            request.downloadHandler = new DownloadHandlerBuffer();
            request.SetRequestHeader("Content-Type", "application/json");
            
            yield return request.SendWebRequest();
            
            if (request.result == UnityWebRequest.Result.Success)
            {
                Debug.Log("服务器清理完成");
                yield return SyncItemsFromServer();
            }
            else
            {
                Debug.LogError($"清理失败: {request.error}");
            }
        }
    }
    
    /// <summary>
    /// 模拟多人同时拾取测试 - 测试服务器的竞争条件处理
    /// </summary>
    IEnumerator SimulateConcurrentPickupTest()
    {
        if (serverItems.Count == 0)
        {
            Debug.LogWarning("没有可拾取的物品用于测试！请先生成一个物品。");
            yield break;
        }
        
        // 选择第一个可拾取的物品进行测试
        var testItem = serverItems.First();
        Vector3 testPosition = Vector3.zero; // 使用原点位置进行测试
        
        Debug.Log($"开始多人竞争拾取测试");
        Debug.Log($"目标物品: {testItem.ItemId}");
        Debug.Log($"虚拟玩家数量: {concurrentPlayersCount}");
        Debug.Log($"请求间隔: {requestDelay * 1000:F0}ms");
        
        // 生成虚拟玩家ID列表
        List<string> virtualPlayerIds = new List<string>();
        for (int i = 0; i < concurrentPlayersCount; i++)
        {
            virtualPlayerIds.Add($"test_player_{UnityEngine.Random.Range(1000, 9999)}_{i}");
        }
        
        // 同时发送多个拾取请求
        List<Coroutine> pickupCoroutines = new List<Coroutine>();
        
        for (int i = 0; i < virtualPlayerIds.Count; i++)
        {
            string playerId = virtualPlayerIds[i];
            
            // 稍微错开请求时间，模拟网络延迟
            if (i > 0)
            {
                yield return new WaitForSeconds(requestDelay);
            }
            
            Coroutine pickupCoroutine = StartCoroutine(
                SimulatePickupRequest(playerId, testItem.ItemId, testPosition, i + 1)
            );
            pickupCoroutines.Add(pickupCoroutine);
        }
        
        // 等待所有请求完成
        foreach (var coroutine in pickupCoroutines)
        {
            yield return coroutine;
        }
        
        // 测试完成后同步物品列表
        yield return new WaitForSeconds(1f);
        yield return SyncItemsFromServer();
    }
    
    /// <summary>
    /// 模拟单个玩家的拾取请求
    /// </summary>
    IEnumerator SimulatePickupRequest(string playerId, string itemId, Vector3 playerPosition, int playerIndex)
    {
        var pickupRequest = new PickupRequest(playerId, itemId, playerPosition);
        string jsonData = JsonUtility.ToJson(pickupRequest);
        
        Debug.Log($"虚拟玩家 #{playerIndex} ({playerId[..10]}...) 尝试拾取物品 {itemId}");
        
        using (UnityWebRequest request = new UnityWebRequest($"{serverUrl}/api/Pickup/pickup", "POST"))
        {
            byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonData);
            request.uploadHandler = new UploadHandlerRaw(bodyRaw);
            request.downloadHandler = new DownloadHandlerBuffer();
            request.SetRequestHeader("Content-Type", "application/json");
            
            float startTime = Time.time;
            yield return request.SendWebRequest();
            float endTime = Time.time;
            float responseTime = (endTime - startTime) * 1000f; // 转换为毫秒
            
            if (request.result == UnityWebRequest.Result.Success)
            {
                try
                {
                    var response = JsonUtility.FromJson<PickupResponse>(request.downloadHandler.text);
                    
                    if (response.Success)
                    {
                        Debug.Log($"虚拟玩家 #{playerIndex} 拾取成功！响应时间: {responseTime:F1}ms");
                        Debug.Log($"消息: {response.Message}");
                    }
                    else
                    {
                        Debug.Log($"虚拟玩家 #{playerIndex} 拾取失败，响应时间: {responseTime:F1}ms");
                        Debug.Log($"原因: {response.Message}");
                    }
                }
                catch (Exception ex)
                {
                    Debug.LogError($"虚拟玩家 #{playerIndex} 响应解析失败: {ex.Message}");
                }
            }
            else
            {
                Debug.LogError($"虚拟玩家 #{playerIndex} 网络请求失败: {request.error}");
            }
        }
    }
    
    /// <summary>
    /// 比较两个物品列表是否相等
    /// </summary>
    bool AreItemListsEqual(List<PickupItem> list1, List<PickupItem> list2)
    {
        if (list1.Count != list2.Count) return false;
        
        var ids1 = list1.Select(item => item.ItemId).OrderBy(id => id).ToList();
        var ids2 = list2.Select(item => item.ItemId).OrderBy(id => id).ToList();
        
        return ids1.SequenceEqual(ids2);
    }
    
    /// <summary>
    /// 获取本地玩家ID
    /// </summary>
    string GetLocalPlayerId()
    {
        // 尝试从NetworkManager获取
        if (networkManager != null)
        {
            // 查找本地玩家的NetworkBehaviour
            var playerBehaviours = FindObjectsOfType<NetworkBehaviour>();
            foreach (var behaviour in playerBehaviours)
            {
                if (behaviour.IsLocalPlayer())
                {
                    return behaviour.GetNetworkId();
                }
            }
        }
        
        return null;
    }
    
    /// <summary>
    /// 查找玩家Transform
    /// </summary>
    void FindPlayerTransform()
    {
        // 查找本地玩家的Transform
        var playerBehaviours = FindObjectsOfType<NetworkBehaviour>();
        foreach (var behaviour in playerBehaviours)
        {
            if (behaviour.IsLocalPlayer())
            {
                playerTransform = behaviour.transform;
                break;
            }
        }
        
        if (playerTransform == null)
        {
            Debug.LogWarning("未找到本地玩家Transform");
        }
    }
}